<?php

namespace app\admins\controller;

use think\facade\Db;
use think\facade\Log;

class TestDemo extends Base
{
    // 列表
    public function index()
    {
        if ($this->request->isAjax()) {
            $param = $this->request->param();
            // 搜索
            $map = [];
            if (!empty($param['search'])) {
                foreach ((array)$param['search'] as $k => $v) {
                    if (strlen($v)) $map[] = [$k, 'like', "%{$v}%"];
                }
            }
            // 查询
            $list = Db::table('test')->where($map)->order('id', 'desc');
            $data['count'] = $list->count();
            if ($data['count']) {
                $data['code'] = 0;
            } else {
                $data['code'] = 1;
                $data['msg'] = '暂无记录';
            }
            // 分页
            $list = $list->page($param['page'], $param['limit']);
            // 渲染
            $list = $list->select()->map(function ($item) {
                $item['time'] = date('Y-m-d H:i:s', $item['time']);
                return $item;
            });
            $data['data'] = $list->toArray();
            return json($data);
        }
        return view('/testdemo/index');
    }

    // 列表（表头型）
    public function table()
    {
        if ($this->request->isAjax()) {
            $param = $this->request->param();
            // 搜索
            $map = [];
            if (!empty($param['search'])) {
                foreach ((array)$param['search'] as $k => $v) {
                    if (strlen($v)) $map[] = [$k, 'like', "%{$v}%"];
                }
            }
            // 分页查询
            $list = Db::table('test')->where($map)->order('id', 'desc')->paginate($param['limit'])->each(function ($item, $key) {
                $item['time'] = date('Y-m-d H:i:s', $item['time']);
                return $item;
            });
            $data['count'] = $list->total();
            if ($data['count']) {
                $data['code'] = 0;
            } else {
                $data['code'] = 1;
                $data['msg'] = '暂无记录';
            }
            $data['data'] = $list->items();
            return json($data);
        }
        return view('/testdemo/table');
    }

    // 列表（手动型）
    public function manual()
    {
        $map = [];
        $search = input('get.search');
        if (!empty($search)) {
            foreach ((array)$search as $k => $v) {
                if (strlen($v)) $map[] = [$k, 'like', "%{$v}%"];
            }
        }
        $data['search'] = (array)$search;
        $data['page'] = max(1, (int)input('get.page'));
        $data['pageSize'] = (int)input('get.limit', 10);
        // 分页查询
        $list = Db::table('test')->where($map)->order('id', 'desc')->paginate($data['pageSize'])->each(function ($item, $key) {
            $item['time'] = date('Y-m-d H:i:s', $item['time']);
            return $item;
        });
        $data['total'] = $list->total();
        $data['items'] = $list->items();
        return view('/testdemo/manual', $data);
    }

    // 列表（转换型）
    public function convert()
    {
        $map = [];
        $search = input('get.search');
        if (!empty($search)) {
            foreach ((array)$search as $k => $v) {
                if (strlen($v)) $map[] = [$k, 'like', "%{$v}%"];
            }
        }
        $data['search'] = (array)$search;
        $data['page'] = max(1, (int)input('get.page'));
        $data['pageSize'] = (int)input('get.limit', 10);
        // 分页查询
        $list = Db::table('test')->where($map)->order('id', 'desc')->paginate($data['pageSize'])->each(function ($item, $key) {
            $item['time'] = date('Y-m-d H:i:s', $item['time']);
            return $item;
        });
        $data['total'] = $list->total();
        $data['items'] = $list->items();
        return view('/testdemo/convert', $data);
    }

    // 列表（大数据分页）
    public function million()
    {
        $data['page'] = max(1, (int)input('get.page'));
        $data['pageSize'] = (int)input('get.limit', 10);
        // 大数据分页查询
        $list = Db::table('test')->paginateX($data['pageSize'], 'id', 'desc')->each(function ($item, $key) {
            $item['time'] = date('Y-m-d H:i:s', $item['time']);
            return $item;
        });
        $data['total'] = Db::table('test')->field('id')->count();
        $data['items'] = $list->items();
        return view('/testdemo/million', $data);
    }

    // Db演示代码
    public function codes()
    {
        $path = $this->app->getRootPath() . 'app/admins/';
        $data['controller'] = file_get_contents($path . 'controller/Testdemo.php');
        $data['add'] = file_get_contents($path . 'view/testdemo/add.html');
        $data['edit'] = file_get_contents($path . 'view/testdemo/edit.html');
        $data['index'] = file_get_contents($path . 'view/testdemo/index.html');
        $data['table'] = file_get_contents($path . 'view/testdemo/table.html');
        $data['manual'] = file_get_contents($path . 'view/testdemo/manual.html');
        $data['convert'] = file_get_contents($path . 'view/testdemo/convert.html');
        $data['million'] = file_get_contents($path . 'view/testdemo/million.html');
        return view('/testdemo/codes', $data);
    }

    // 添加
    public function add()
    {
        return view('/testdemo/add');
    }

    // 保存
    public function save()
    {
        // 验证
        $this->check(['__token__', 'meta_key', 'meta_value', 'status']);
        // 数据
        $data = $this->request->only(['meta_key', 'meta_value', 'status']); //允许的字段
        $data['time'] = time();
        // 操作
        try {
            Db::table('test')->insert($data);
        } catch (\Exception $e) {
            $this->log($e->getMessage(), __LINE__ - 2);
            $this->err(['code' => 1, 'msg' => '保存失败']);
        }
        $this->err(['code' => 0, 'msg' => '保存成功']);
    }

    // 编辑
    public function edit()
    {
        $id = (int)input('get.id');
        $row = Db::table('test')->where('id', $id)->find();
        empty($row) && $this->err(['code' => 1, 'msg' => '数据不存在']);
        // 渲染
        $data['row'] = $row;
        return view('/testdemo/edit', $data);
    }

    // 保存编辑
    public function save_edit()
    {
        // 验证
        $this->check(['__token__', 'id', 'meta_key', 'meta_value', 'status']);
        $id = (int)input('post.id');
        $row = Db::table('test')->where('id', $id)->find();
        empty($row) && $this->err(['code' => 1, 'msg' => '数据不存在']);
        // 数据
        $data = $this->request->only(['meta_key', 'meta_value', 'status']); //允许的字段
        // 操作
        try {
            Db::table('test')->where('id', $row['id'])->update($data);
        } catch (\Exception $e) {
            $this->log($e->getMessage(), __LINE__ - 2);
            $this->err(['code' => 1, 'msg' => '保存失败']);
        }
        $this->err(['code' => 0, 'msg' => '保存成功']);
    }

    // 删除
    public function del()
    {
        $id = (array)input('post.id');
        $rows = Db::table('test')->whereIn('id', $id)->select();
        $rows->isEmpty() && $this->err(['code' => 1, 'msg' => '数据不存在']);
        // 操作
        try {
            Db::table('test')->whereIn('id', $id)->delete();
        } catch (\Exception $e) {
            $this->log($e->getMessage(), __LINE__ - 2);
            $this->err(['code' => 1, 'msg' => '删除失败']);
        }
        $this->err(['code' => 0, 'msg' => '删除成功']);
    }

    // 属性修改
    public function modify()
    {
        // 验证
        try {
            $this->validate($this->request->post(), [
                'id|ID' => 'require|number',
                'field|字段' => 'require',
                'value|值' => 'require',
            ]);
        } catch (\Exception $e) {
            $this->err(['code' => 1, 'msg' => $e->getMessage()]);
            exit();
        }
        $id = (int)input('post.id');
        $row = Db::table('test')->where('id', $id)->find();
        empty($row) && $this->err(['code' => 1, 'msg' => '数据不存在']);
        // 非法字段
        $field = input('post.field');
        $value = input('post.value');
        (empty($field) || !is_string($field)) && $this->err(['code' => 1, 'msg' => '字段错误']);
        is_null($value) && $this->err(['code' => 1, 'msg' => '值错误']);
        !in_array($field, ['meta_key', 'meta_value', 'status']) && $this->err(['code' => 1, 'msg' => '该字段不允许修改']); //允许的字段
        // 验证属性
        $data = [$field => $value];
        $this->check([$field], $data);
        // 操作
        try {
            Db::table('test')->where('id', $id)->update($data);
        } catch (\Exception $e) {
            $this->log($e->getMessage(), __LINE__ - 2);
            $this->err(['code' => 1, 'msg' => '修改失败']);
        }
        $this->err(['code' => 0, 'msg' => '修改成功']);
    }

    // 私有方法：验证
    private function check($field = [], $data = null)
    {
        $rule = [
            '__token__' => 'require|token',
            'id|ID' => 'require|number',
            'meta_key|键' => 'require|alphaDash|unique:test', //验证token且数据表值唯一
            'meta_value|值' => 'requireWith:meta_value|chsDash',
            'status|状态' => 'require|in:0,1',
        ];
        $validate = [];
        foreach ($rule as $key => $value) {
            [$name,] = explode('|', $key);
            if (in_array($name, $field)) {
                $validate[$key] = $value;
            }
        }
        try {
            $this->validate($data ?: $this->request->post(), $validate);
        } catch (\Exception $e) {
            $this->err(['code' => 1, 'msg' => $e->getMessage()]);
            exit;
        }
    }

    // 私有方法：错误消息
    private function err($args = ['code' => 1, 'msg' => 'Error!'])
    {
        if ($this->request->isAjax()) {
            echo json_encode($args);
        } else {
            if (!empty($args['msg']))
                echo '<p style="text-align:center;color:#393D49;font-size:20px;">' . $args['msg'] . '</p>';
            if (!empty($args['url'])) {
                echo '<script>
                    setTimeout(function () {
                        var _ta = window.location;
                        if (self.frameElement && self.frameElement.tagName == "IFRAME") {
                            _ta = parent.window.location;
                        }
                        _ta.href = "' . $args['url'] . '";
                    }, 1000);
                    </script>';
            }
        }
        if (!empty($args['code'])) exit;
    }

    // 私有方法：错误日志
    private function log($msg, $line)
    {
        Log::write('/' . $this->app->http->getName() . '/' . $this->request->controller() . '/' . $this->request->action() . ' -> Line ' . $line . ': ' . $msg, 'notice');
    }
}
